package com.xdf.xzymanagementsystem.service.impl;

import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.xdf.xzymanagementsystem.dao.*;
import com.xdf.xzymanagementsystem.entity.*;
import com.xdf.xzymanagementsystem.enums.BillCodeResetEnum;
import com.xdf.xzymanagementsystem.service.OrderMainService;
import com.xdf.xzymanagementsystem.util.CodeGenUtil;
import com.xdf.xzymanagementsystem.util.SystemUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @Description : 服务层实现类，由代码生成器自动生成
 * @Author : chanchaw
 * @Date : 2025-3-21 18:43:41
 */
@Slf4j
@Service
public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain> implements OrderMainService {
    @Autowired
    private OrderMainMapper dao;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private SystemUtils systemUtils;
    @Autowired
    private CodeGenUtil codeGenUtil;
    @Autowired
    private GreyMainMapper greyMainMapper;
    @Autowired
    private HalfMainMapper halfMainMapper;
    @Autowired
    private ProductMainMapper productMainMapper;
    @Autowired
    private JcContactcompanyMapper jcContactcompanyMapper;
    //=================以上是自动生成的代码，自定义代码请写在下面==================
    @Override
    public List<Map<String, Object>> selectAllDTO(Date sdate, Date edate, int flag) {
        return dao.selectAllDTO(sdate, edate, flag);
    }

    //新增单据
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderMainDTO insertDTO(OrderMainDTO record) throws Exception {
        if (selectRepeatOrderNo(record.getOrderNo()) != null) throw new RuntimeException("订单号已存在,不允许重复！！");
        OrderMain orderMain = new OrderMain();
        BeanUtils.copyProperties(record, orderMain);
        orderMain.setCreateUser(systemUtils.getLoginUsername());
        orderMain.setState(1);
        orderMain.setBillCode(getBillCode());
        dao.insertSelective(orderMain);//新增主表数据
        List<OrderDetail> detailList = record.getDetailList();
        for (OrderDetail orderDetail : detailList) {
            orderDetail.setParentId(orderMain.getId());//关联主表id
            orderDetail.setState(1);
            orderDetail.setCreateUser(systemUtils.getLoginUsername());
            orderDetail.setQty(orderDetail.getQty().setScale(2, RoundingMode.HALF_UP));
            orderDetail.setPrice(orderDetail.getPrice().setScale(2, RoundingMode.HALF_UP));
            orderDetail.setAmount(orderDetail.getAmount().setScale(2, RoundingMode.HALF_UP));
            orderDetailMapper.insertSelective(orderDetail);
        }
        //获取数据并返回
        OrderMainDTO orderMainDTO = selectDTO(orderMain.getId());
        return orderMainDTO;
    }

    //检测订单号是否重复
    private OrderMain selectRepeatOrderNo(String orderNo) {
        return dao.selectRepeatOrderNo(orderNo);
    }

    //生成单据编号
    private String getBillCode() {
        OrderMain orderMain = dao.selectMaxBillCode();
        int year = LocalDate.now().getYear();
        int monthValue = LocalDate.now().getMonthValue();
        int day = LocalDate.now().getDayOfMonth();
        if (orderMain != null) {
            String billCode = orderMain.getBillCode();
            int codeNumber = Integer.parseInt(billCode.substring(8));
            int dayNumber = Integer.parseInt(billCode.substring(6, 8));
            if (dayNumber != day) {
                codeNumber = 0;
            }
            return "DR" + String.valueOf(year).substring(2) + String.format("%02d", monthValue) + String.format("%02d", day)  + String.format("%03d", codeNumber + 1);
        }else {
            return "DR" + String.valueOf(year).substring(2) + String.format("%02d", monthValue) + String.format("%02d", day)  + String.format("%03d", 1);
        }
    }

    @Override
    public OrderMainDTO selectDTO(Integer id) {
        OrderMainDTO orderMainDTO = new OrderMainDTO();
        OrderMain main = dao.selectById(id);//查询主表
        List<OrderDetail> details = orderDetailMapper.selectByParentId(id);
        BeanUtils.copyProperties(main, orderMainDTO);
        orderMainDTO.setDetailList(details);
        return orderMainDTO;
    }

    //修改单据
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrderMainDTO updateDTO(OrderMainDTO record) {
        OrderMain main = selectRepeatOrderNo(record.getOrderNo());
        //订单号相同，id不同
        if (main != null) {
            if (main.getOrderNo().equals(record.getOrderNo()) && !main.getId().equals(record.getId())) throw new RuntimeException("订单号已存在,不允许重复！！");
        }
        List<OrderDetail> detailList = record.getDetailList();
        OrderMain orderMain = new OrderMain();
        BeanUtils.copyProperties(record, orderMain);
        orderMain.setUpdateTime(new Date());
        orderMain.setUpdateUser(systemUtils.getLoginUsername());
        if (dao.update(orderMain) < 0) throw new RuntimeException("修改主表时发生错误！");
        for (OrderDetail orderDetail : detailList) {
            if (Optional.ofNullable(orderDetail.getId()).orElse(0) == 0) {
                orderDetail.setParentId(orderMain.getId());//关联主表id
                orderDetail.setState(1);
                orderDetail.setCreateUser(systemUtils.getLoginUsername());
                orderDetail.setQty(orderDetail.getQty().setScale(2, RoundingMode.HALF_UP));
                orderDetail.setPrice(orderDetail.getPrice().setScale(2, RoundingMode.HALF_UP));
                orderDetail.setAmount(orderDetail.getAmount().setScale(2, RoundingMode.HALF_UP));
                orderDetailMapper.insertSelective(orderDetail);
            }
            orderDetail.setUpdateTime(new Date());
            orderDetail.setUpdateUser(systemUtils.getLoginUsername());
            if (orderDetailMapper.update(orderDetail) < 0) throw new RuntimeException("修改明细时发生错误！");
        }
        List<OrderDetail> details = orderDetailMapper.selectByParentId(record.getId());
        //删除掉删除行的明细
        List<OrderDetail> extraDetails = getDeleteDetails(detailList, details);
        if (extraDetails.size() > 0) {
            for (OrderDetail extraDetail : extraDetails) {
                orderDetailMapper.deleteById(extraDetail.getId());
            }
        }
        return selectDTO(record.getId());
    }

    //查询过滤删除行的明细
    private static List<OrderDetail> getDeleteDetails(List<OrderDetail> detailList, List<OrderDetail> details) {
        // 提取detailList中所有元素的ID集合
        Set<Integer> detailIds = detailList.stream()
                .map(OrderDetail::getId)
                .collect(Collectors.toSet());
        // 过滤出details中ID不在detailIds的元素
        List<OrderDetail> extraDetails = details.stream()
                .filter(d -> !detailIds.contains(d.getId()))
                .collect(Collectors.toList());
        return extraDetails;
    }

    //批量删除
    @Override
    public void deleteByIds(List<Integer> ids) {
        for (Integer id : ids) {
            OrderMain orderMain = dao.selectById(id);
            List<GreyMain> gmList = greyMainMapper.selectByOrderNo(orderMain.getOrderNo());
            List<HalfMain> hmList = halfMainMapper.selectByOrderNo(orderMain.getOrderNo());
            List<ProductMain> cpList = productMainMapper.selectByOrderNo(orderMain.getOrderNo());
            if (gmList.size() > 0 || hmList.size() > 0 || cpList.size() > 0) throw new RuntimeException("该订单已进入业务流程，不允许删除！！");
            List<OrderDetail> details = orderDetailMapper.selectByParentId(id);
            if (details.size() > 0) {
                for (OrderDetail detail : details) {
                    detail.setIsDelete(1);
                    detail.setUpdateUser(systemUtils.getLoginUsername());
                    detail.setUpdateTime(new Date());
                    orderDetailMapper.update(detail);
                }
            }
            orderMain.setIsDelete(1);
            orderMain.setUpdateUser(systemUtils.getLoginUsername());
            orderMain.setUpdateTime(new Date());
            dao.update(orderMain);
        }
    }

    //根据订单号查询单据
    @Override
    public OrderMainDTO selectByOrderNoDTO(String orderNo, int flag) {
        OrderMain orderMain = selectRepeatOrderNo(orderNo);
        if (orderMain == null) throw new RuntimeException("该订单号不存在！！");
        OrderMainDTO orderMainDTO = new OrderMainDTO();
        List<OrderDetail> detailList = orderDetailMapper.selectByParentId(orderMain.getId());
        if (detailList.size() == 0) throw new RuntimeException("该订单号下位查询到订单明细！！");
        BeanUtils.copyProperties(orderMain, orderMainDTO);
        if (flag == 1) {
            List<OrderDetail> distinctList = detailList.stream()
                    .filter(distinctByKey(detail -> Arrays.asList(detail.getGrayName(), detail.getGraySpecification())))
                    .collect(Collectors.toList());
            orderMainDTO.setDetailList(distinctList);
        } else {
            orderMainDTO.setDetailList(detailList);
        }
        Date billDate = orderMainDTO.getBillDate();
        // 创建 SimpleDateFormat 对象，指定格式为 "yyyy-MM-dd"
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // 格式化 Date 对象
        String formattedDate = sdf.format(billDate);
        JcContactcompany jcContactcompany = jcContactcompanyMapper.selectByPrimaryKey(orderMainDTO.getClientId());
        orderMainDTO.setSysRemark(jcContactcompany.getCtName() + ", " + formattedDate);
        return orderMainDTO;
    }

    @Override
    public List<OrderDetail> selectByOrderDetail(String orderNo) {
        OrderMain orderMain = dao.selectRepeatOrderNo(orderNo);
        return orderDetailMapper.selectByParentId(orderMain.getId());
    }

    @Override
    public List<Map<String, Object>> listQuery() {
        List<Map<String, Object>> orderNoList = dao.selectAllOrderNo();
        return orderNoList;
    }

    @Override
    public List<Map<String, Object>> listQueryAll() {
        List<Map<String, Object>> orderNoList = dao.selectAllOrderNo2();
        return orderNoList;
    }

    @Override
    public List<Map<String, Object>> selectAllsum(Date sdate, Date edate, int flag) {
        return dao.selectAllsum(sdate, edate, flag);
    }

    @Override
    public List<Map<String, Object>> selectAllmain(Date sdate, Date edate, int flag) {
        return dao.selectAllmain(sdate, edate, flag);
    }

    @Override
    public List<Map<String, Object>> selectAlldetail(String orderNo) {
        return dao.selectAlldetail(orderNo);
    }

    // 自定义去重过滤器
    private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Set<Object> seen = ConcurrentHashMap.newKeySet();
        return t -> seen.add(keyExtractor.apply(t));
    }
}